package main // 声明 main 包，表明当前是一个可执行程序

import (
	"fmt" // 导入内置 fmt
	"go-demo/example"
	_ "go-demo/importtest"
	"math"
	"math/rand"
	"strconv"
	"time"
)

func traversalString() {
	s := "pprof.cn博客"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i])
	}
	fmt.Println()
	for _, r := range s { //rune
		fmt.Printf("%v(%c) ", r, r)
	}
	fmt.Println()
}

func changeString() {
	s1 := "hello"
	// 强制类型转换
	byteS1 := []byte(s1)
	byteS1[0] = 'H'
	fmt.Println(string(byteS1))

	s2 := "博客"
	runeS2 := []rune(s2)
	runeS2[0] = '狗'
	fmt.Println(string(runeS2))
}

var arr0 [5]int = [5]int{1, 2, 3}
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}
var str = [5]string{3: "hello world", 4: "tom"}

func sqrtDemo() {
	var a, b = 3, 4
	// math.Sqrt()接收的参数是float64类型，需要强制转换
	c := int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c)
}

var arr3 [5][3]int
var arr4 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

func test(x [2]int) {
	fmt.Printf("x: %p\n", &x)
	x[1] = 1000
}

func printArr(arr *[5]int) {
	arr[0] = 10
	for i, v := range arr {
		fmt.Println(i, v)
	}
}

// 求元素和
func sumArr(a [10]int) int {
	var sum int = 0
	for i := 0; i < len(a); i++ {
		sum += a[i]
	}
	return sum
}

// 找出数组中和为给定值的两个元素的下标，例如数组[1,3,5,8,7]，
// 找出两个元素之和等于8的下标分别是（0，4）和（1，2）

// 求元素和，是给定的值
func myTest(a [5]int, target int) {
	// 遍历数组
	for i := 0; i < len(a); i++ {
		other := target - a[i]
		// 继续遍历
		for j := i + 1; j < len(a); j++ {
			if a[j] == other {
				fmt.Printf("(%d,%d)\n", i, j)
			}
		}
	}
}

func main() { // main函数，是程序执行的入口

	fileSize, err := strconv.ParseInt("1048576000", 10, 64)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("fileSize=", fileSize)

	fmt.Println("Hello World!") // 在终端打印 Hello World!
	fmt.Println(example.Add(1, 2))
	traversalString()
	changeString()
	sqrtDemo()

	a := [3]int{1, 2}           // 未初始化元素值为 0。
	b := [...]int{1, 2, 3, 4}   // 通过初始化值确定数组长度。
	c := [5]int{2: 100, 4: 200} // 使用引号初始化元素。
	d := [...]struct {
		name string
		age  uint8
	}{
		{"user1", 10}, // 可省略元素类型。
		{"user2", 20}, // 别忘了最后一行的逗号。
	}
	fmt.Println(arr0, arr1, arr2, str)
	fmt.Println(a, b, c, d)

	a1 := [2][3]int{{1, 2, 3}, {4, 5, 6}}
	b1 := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。
	fmt.Println(arr3, arr4)
	fmt.Println(a1, b1)

	a2 := [2]int{}
	fmt.Printf("a2: %p\n", &a2)

	test(a2)
	fmt.Println(a2)

	a3 := [2]int{}
	fmt.Println("len(a3): ", len(a3), "cap(a3): ", cap(a3))

	var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

	for k1, v1 := range f {
		for k2, v2 := range v1 {
			fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
		}
		fmt.Println()
	}

	var arr1 [5]int
	printArr(&arr1)
	fmt.Println(arr1)
	arr2 := [...]int{2, 4, 6, 8, 10}
	printArr(&arr2)
	fmt.Println(arr2)

	// 若想做一个真正的随机数，要种子
	// seed()种子默认是1
	//rand.Seed(1)
	fmt.Println(time.Now().Unix())
	rand.Seed(time.Now().Unix())

	var b2 [10]int
	for i := 0; i < len(b2); i++ {
		// 产生一个0到1000随机数
		b2[i] = rand.Intn(1000)
	}
	sum := sumArr(b2)
	fmt.Printf("sum=%d\n", sum)

	b3 := [5]int{1, 3, 5, 8, 7}
	myTest(b3, 8)
}
